"use strict";
exports.__esModule = true;
var xlsx = require("node-xlsx");
var fs = require("fs");
var path = require("path");
console.log();
var config = require("./config.json");
var Idx = { "server": 0, "client": 1 };
var TypeMap = { "bool": "boolean", "int": "number" };
/**
 * 开始执行
 */
function start() {
    var inputfiles = [];
    try {
        inputfiles = fs.readdirSync(config.input);
    }
    catch (e) {
        return console.error("directory input ", "非法输入路径", config.input);
    }
    // 服务端
    if (config.server) {
        // 没有目录就直接创建
        if (!fs.existsSync(config.s_output)) {
            fs.mkdirSync(config.s_output);
        }
        if (!fs.existsSync(config.s_ts_output)) {
            fs.mkdirSync(config.s_ts_output);
        }
        var declares_1 = [];
        // 导出
        inputfiles.forEach(function (filename) { return parse(filename, config.s_output, "server", declares_1); });
        // 导出ts类型声明文件
        wirte2ts(declares_1, config.s_ts_output, "server");
    }
    console.log();
    // 客户端
    if (config.client) {
        // 没有目录就直接创建
        if (!fs.existsSync(config.c_output)) {
            fs.mkdirSync(config.c_output);
        }
        if (!fs.existsSync(config.c_ts_output)) {
            fs.mkdirSync(config.c_ts_output);
        }
        var declares_2 = [];
        // 导出json
        inputfiles.forEach(function (filename) { return parse(filename, config.c_output, "client", declares_2); });
        // 导出ts类型声明文件
        wirte2ts(declares_2, config.c_ts_output, "client");
    }
}
/**
 * 创建ts类型声明文件
 * @param declares 类型包装类
 * @param outDir 输出目录
 * @param outType 输出类型
 */
function wirte2ts(declares, outDir, outType) {
    console.log();
    var str = "/** 配置文件的类型定义 */\n";
    str += "declare namespace ConfigTypes {\n";
    for (var _i = 0, declares_3 = declares; _i < declares_3.length; _i++) {
        var it = declares_3[_i];
        str += "\t/** " + it.m_comm + "-" + it.i_comm + " */\n";
        str += "\ttype " + it.m_class + it.i_class + "Config = {\n";
        for (var _a = 0, _b = it.fields; _a < _b.length; _a++) {
            var field = _b[_a];
            str += "\t\t/** " + field.comm + " */\n";
            str += "\t\t" + field.name + ",\n";
        }
        str += "\t}\n";
    }
    str += "\n}";
    var fileName = "configuration.d.ts";
    // 输出路径
    var outpath = path.join(outDir, fileName);
    // 写入文件
    fs.writeFileSync(outpath, str);
    console.log("------ >>> input to " + outType + " --- excel >>> " + config.input + " --- to ts >>> " + fileName);
}
/**
 * 解析单个表
 * @param filename 表格文件名
 * @param outDir 输出目录
 * @param outType 输出类型
 * @param declares ts类型声明包装类
 * @returns
 */
function parse(filename, outDir, outType, declares) {
    if (filename[0] === "~") {
        return;
    }
    if (!filename.endsWith(".xlsx")) {
        return;
    }
    // 读取excel文件
    var buff = fs.readFileSync(path.join(config.input, filename));
    // 解析大模块的名称和注释
    var mNames = path.basename(filename, '.xlsx').split("-");
    if (mNames.length != 2 || !mNames[1] || !mNames[0]) {
        console.error("\u4E22\uFF01\u8C01\u5141\u8BB8\u4F60\u4E0D\u5199\u6CE8\u91CA\uFF1F\u4E0D\u5199\u6A21\u5757\u540D\u79F0\uFF1F\u4E0D\u7ED9\u5BFC\u51FA\u3002\u6A21\u5757\uFF1A" + mNames[0] + " \u6CE8\u91CA\uFF1A" + mNames[1]);
        return;
    }
    var sheets = xlsx.parse(buff, { "raw": false });
    for (var _i = 0, sheets_1 = sheets; _i < sheets_1.length; _i++) {
        var sheet = sheets_1[_i];
        var lists = sheet.data;
        if (lists.length === 0) {
            continue;
        }
        // 类型声明对象创建添加
        var tsObj = { m_comm: "", i_comm: "", m_class: "", i_class: "", fields: [] };
        // 模块 名称
        tsObj.m_class = toUpStart(mNames[0]);
        // 模块 类型注释
        tsObj.m_comm = mNames[1];
        var classNames = sheet.name.split("-");
        if (classNames.length != 2 || !classNames[1] || !classNames[0]) {
            console.error("\u4E22\uFF01\u8C01\u5141\u8BB8\u4F60\u4E0D\u5199\u6CE8\u91CA\uFF1F\u4E0D\u5199\u5B50\u6A21\u5757\u540D\u79F0\uFF1F\u4E0D\u7ED9\u5BFC\u51FA\u3002\u6A21\u5757\uFF1A" + mNames[0] + " \u5B50\u6A21\u5757\uFF1A" + classNames[0] + " \u6CE8\u91CA\uFF1A" + classNames[1]);
            return;
        }
        // 小模块名称
        tsObj.i_class = toUpStart(classNames[0]);
        // 小模块注释
        tsObj.i_comm = classNames[1];
        /** 类型 数组 */
        var types = lists[Idx[outType]];
        /** 属性名 数组 */
        var fields = lists[2];
        /** 注释 数组 */
        var comments = lists[3];
        // 第二列开始才是真的属性类型
        for (var i = 2; i < fields.length; i++) {
            var type_1 = types[i];
            if (type_1 === "no") {
                continue;
            }
            var field = { name: "", comm: "" };
            var tsType = TypeMap[type_1];
            if (!tsType) {
                tsType = type_1.replace("int", "number").replace("bool", "boolean");
            }
            field.name = fields[i] + ": " + tsType;
            field.comm = comments[i];
            tsObj.fields.push(field);
        }
        declares.push(tsObj);
        /** 是否导出为数组 */
        var isArray = !!config.isArray;
        /** 服务端 导出的数据 */
        var obj = isArray ? { "data": [] } : {};
        // 前3行是注释等配置，后面的才是数据
        for (var i = 4; i < lists.length; i++) {
            // 是否导出
            if (!lists[i][0]) {
                continue;
            }
            // 必须要有 唯一值key
            if (lists[i][1] === undefined) {
                continue;
            }
            var tmpInfo = createObj(fields, types, lists[i]);
            if (isArray) {
                obj.data.push(tmpInfo);
            }
            else {
                obj[lists[i][1]] = tmpInfo;
            }
        }
        // 格式化的间隔
        var spaceNum = !!config.isPretty ? 4 : 0;
        // json文件名
        var fileName = mNames[0] + "_" + classNames[0] + ".ts";
        // 输出路径
        var outpath = path.join(outDir, fileName);
        var dataStr = JSON.stringify(obj, null, spaceNum)
        var resultStr = "export var lanValue = " + dataStr
        // 写入文件
        fs.writeFileSync(outpath, resultStr);
            // JSON.stringify(obj, null, spaceNum));
        // 输出提示
        console.log("------ >>> input to " + outType + " --- excel >>> " + config.input + " --- to json >>> " + fileName);
    }
}
/**
 * 创建单个对象
 * @param fields 属性名数组
 * @param types 类型数组
 * @param datas 数据
 * @returns
 */
function createObj(fields, types, datas) {
    var obj = {};
    for (var i = 2; i < fields.length; i++) {
        var type_2 = types[i];
        // 该字段在服务端是否要导出
        if (type_2 === "no") {
            continue;
        }
        var value = datas[i];
        if (value === undefined) {
            value = "";
        }
        var key = fields[i];
        if (type_2 === "bool") {
            value = value.trim().toLowerCase();
            if (value === "0" || value == "" || value === "false") {
                obj[key] = false;
            }
            else if (value === "1" || value === "true") {
                obj[key] = true;
            }
            console.error("配置类型值错误：type：", type_2, " value：", value);
            process.exit();
        }
        else if (type_2 === "string") {
            obj[key] = value;
        }
        else if (type_2 === "int") {
            obj[key] = Number(value) || 0;
        }
        else {
            // const tsType = type.replace("int", "number").replace("bool", "boolean")
            // console.log("tsType : ", tsType)
            obj[key] = JSON.parse(value);
        }
    }
    return obj;
}
/**
 * 把英文改为首字母大写
 * @param str
 * @returns
 */
function toUpStart(str) {
    return str.slice(0, 1).toUpperCase() + str.slice(1);
}
start();
